package com.nongtai.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.nongtai.constant.RedisConstant;
import com.nongtai.exception.InvalidGoodsIdException;
import com.nongtai.exception.InvalidPaginationDataException;
import com.nongtai.exception.NoGoodsException;
import com.nongtai.mapper.*;
import com.nongtai.pojo.dto.SubCategoryGoodsPageDto;
import com.nongtai.pojo.entity.*;
import com.nongtai.pojo.vo.GoodsCategoryVo;
import com.nongtai.pojo.vo.GoodsDetailsVo;
import com.nongtai.pojo.vo.GoodsVo;
import com.nongtai.service.GoodsService;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;

/**
 * 商品相关业务
 *
 * @author yza
 * @version 1.0
 * @date 2024/6/2 12:55
 */
@Service
public class GoodsServiceImpl implements GoodsService {
    @Resource
    private RedisTemplate<String, Object> redisTemplate;
    @Resource
    private GoodsMapper goodsMapper;
    @Resource
    private GoodsDetailsMapper goodsDetailsMapper;
    @Resource
    private BrandMapper brandMapper;
    @Resource
    private GoodsAttributesMapper goodsAttributesMapper;
    @Resource
    private GoodsCategoryMapper goodsCategoryMapper;
    @Resource
    private SpecificationMapper specificationMapper;
    @Resource
    private SkuMapper skuMapper;

    /**
     * 获取所有商品
     *
     * @return
     */
    @Override
    public List<Goods> getAllGoods() {
        QueryWrapper<Goods> goodsQueryWrapper = new QueryWrapper<>();
        goodsQueryWrapper.lt("id", 100);
        List<Goods> goods = goodsMapper.selectList(goodsQueryWrapper);

        return goods;
    }

    /**
     * 根据分类id查找该分类下的所有商品
     *
     * @param id
     * @return
     */
    @Override
    public List<GoodsVo> getGoodsByCategoryId(Long id) {

        QueryWrapper<Goods> goodsQueryWrapper = new QueryWrapper<>();
        goodsQueryWrapper.eq("category_id", id);
        List<Goods> goodsList = goodsMapper.selectList(goodsQueryWrapper);

        List<GoodsVo> goodsVoList = new ArrayList<>();
        for (Goods goods : goodsList) {
            GoodsVo goodsVo = convertToVo(goods);
            goodsVoList.add(goodsVo);
        }

        return goodsVoList;
    }

    /**
     * 根据二级分类id查找该分类下的所有商品
     *
     * @param goodsPageDto 包含二级分类id和分页信息的dto
     * @return
     */
    @Override
    public List<GoodsVo> getGoodsBySubCategoryId(SubCategoryGoodsPageDto goodsPageDto) {
        Integer page = goodsPageDto.getPage();
        Integer pageSize = goodsPageDto.getPageSize();
        if (page <= 0 || pageSize <= 0) {
            throw new InvalidPaginationDataException("非法的分页数据");
        }
        // 计算分页起始下标
        int start = (page - 1) * pageSize;
        List<Goods> goodsList = goodsMapper.selectGoodsBySubCategoryIdPage(start, goodsPageDto.getPageSize(), goodsPageDto.getCategoryId());

        List<GoodsVo> goodsVoList = new ArrayList<>();
        for (Goods goods : goodsList) {
            GoodsVo goodsVo = convertToVo(goods);
            goodsVoList.add(goodsVo);
        }

        return goodsVoList;
    }

    /**
     * 根据商品id返回商品详情信息
     *
     * @param id 商品id
     * @return 商品详情信息
     */
    @Override
    public GoodsDetailsVo getGoodsDetailsById(Long id) {
        if (id == null || id < 0) {
            throw new InvalidGoodsIdException("非法的商品id");
        }
        GoodsDetailsVo goodsDetails = new GoodsDetailsVo();

        // 查询商品基本信息
        Goods goods = goodsMapper.selectByPrimaryKey(id);

        // 查询商品详细信息
        QueryWrapper<GoodsDetails> goodsDetailsQueryWrapper = new QueryWrapper<>();
        goodsDetailsQueryWrapper.eq("goods_id", id);
        GoodsDetails goodsDetailsInfo = goodsDetailsMapper.selectOne(goodsDetailsQueryWrapper);

        // 查询商品对应的品牌
        Brand brand = null;
        if (goodsDetailsInfo != null && goodsDetailsInfo.getBrandId() != null) {
            brand = brandMapper.selectByPrimaryKey(goodsDetailsInfo.getBrandId());
        }

        // 查询商品详情kv对
        QueryWrapper<GoodsAttributes> goodsAttributesQueryWrapper = new QueryWrapper<>();
        goodsAttributesQueryWrapper.eq("goods_id", id);
        List<GoodsAttributes> goodsAttributes = goodsAttributesMapper.selectList(goodsAttributesQueryWrapper);

        // 查询商品分类
        GoodsCategory goodsCategory1 = goodsCategoryMapper.selectByPrimaryKey(goods.getCategoryId());
        GoodsCategory goodsCategory2 = goodsCategoryMapper.selectByPrimaryKey(goods.getCategoryIdDetails());

        // 查询商品规格信息
        List<Spec> specList = specificationMapper.selectAllSpecificationByGoodsId(id);

        // 查询sku
        QueryWrapper<Sku> skuQueryWrapper = new QueryWrapper<>();
        skuQueryWrapper.eq("goods_id", id);
        skuQueryWrapper.select(Arrays.asList("id", "goods_id", "sku_code", "price", "old_price", "inventory", "picture"));
        List<Sku> skus = skuMapper.selectList(skuQueryWrapper);
        for (Sku sku : skus) {
            String skuCode = sku.getSkuCode();
            String[] split = skuCode.split("-");
            List<Sku.Spec> list = new ArrayList<>();
            for (int i = 0;i < specList.size();i++){
                list.add(new Sku.Spec(specList.get(i).getName(),split[i]));
            }
            sku.setSpecs(list);
        }

        if (goods != null) {
            goodsDetails.setId(goods.getId());
            goodsDetails.setName(goods.getName());
            goodsDetails.setDescription(goods.getDescription());
            goodsDetails.setPrice(goods.getPrice());
            goodsDetails.setOldPrice(goods.getPrice());
            goodsDetails.setDiscount(goods.getDiscount());
        }
        if (goodsDetailsInfo != null) {
            goodsDetails.setSpuCode(goodsDetailsInfo.getSpuCode());
            goodsDetails.setIsPreSale(goodsDetailsInfo.getIsPreSale());
            goodsDetails.setInventory(goodsDetailsInfo.getInventory());
            goodsDetails.setSalesCount(goodsDetailsInfo.getSalesCount());
            goodsDetails.setCommentCount(goodsDetailsInfo.getCommentCount());
            goodsDetails.setCollectCount(goodsDetailsInfo.getCollectCount());
        }

        // 设置品牌
        goodsDetails.setBrand(brand);

//        goodsDetails.setMainVideos();
        goodsDetails.setVideoScale(1);
        List<String> mainPictures = new ArrayList<>();
        mainPictures.add(goods.getPicture());
        goodsDetails.setMainPictures(mainPictures);
        goodsDetails.setSpecs(specList);
        goodsDetails.setSkus(skus);

        // 填充商品分类信息
        List<GoodsCategoryVo> categoryList = new ArrayList<>();
        if(goodsCategory1 != null){
            categoryList.add(new GoodsCategoryVo(goodsCategory1.getId(), goodsCategory1.getName(),
                    goodsCategory1.getPicture(), null, null));
        }
        if(goodsCategory2 != null){
            categoryList.add(new GoodsCategoryVo(goodsCategory2.getId(), goodsCategory2.getName(),
                    goodsCategory2.getPicture(), null, null));
        }
        goodsDetails.setCategories(categoryList);

        // 商品详情内容填充
        GoodsDetailsVo.Details details = new GoodsDetailsVo.Details();

        List<GoodsDetailsVo.Details.Property> properties = new ArrayList<>();
        List<String> pictures = new ArrayList<>();

        for (GoodsAttributes goodsAttribute : goodsAttributes) {
            GoodsDetailsVo.Details.Property property = new GoodsDetailsVo.Details.Property();
            property.setName(goodsAttribute.getName());
            property.setValue(goodsAttribute.getValue());
            properties.add(property);
        }

        details.setProperties(properties);
        details.setPictures(pictures);
        goodsDetails.setDetails(details);

        // TODO 商品推荐， 用户地址
        goodsDetails.setUserAddresses(null);
        goodsDetails.setSimilarProducts(null);
        goodsDetails.setHotByDay(null);

        return goodsDetails;
    }

    /**
     * 获取一天的热门商品
     *
     * @param id    当前商品id
     * @param limit 限制返回几条数据
     * @return
     */
    @Override
    public List<GoodsVo> getHotGoodsRankOneDay(Long id, Integer limit) {
        Goods goodsById = goodsMapper.selectByPrimaryKey(id);
        Long categoryId = goodsById.getCategoryIdDetails();
        return getHotGoodsRankByKey(RedisConstant.RANK_HOT_ONE_DAY + ":" + categoryId, limit);
    }

    /**
     * 获取一周的热门商品
     *
     * @param id    当前商品id
     * @param limit 限制返回几条数据
     * @return
     */
    @Override
    public List<GoodsVo> getHotGoodsRankOneWeek(Long id, Integer limit) {
        Goods goodsById = goodsMapper.selectByPrimaryKey(id);
        Long categoryId = goodsById.getCategoryIdDetails();
        return getHotGoodsRankByKey(RedisConstant.RANK_HOT_ONE_WEEK + ":" + categoryId, limit);
    }
    /**
     * 获取总榜的热门商品
     *
     * @param limit 限制返回几条数据
     * @return
     */
    @Override
    public List<GoodsVo> getHotGoodsRankAll(Integer limit) {
        return getHotGoodsRankByKey(RedisConstant.RANK_HOT_ONE_ALL, limit);
    }

    /**
     * 根据redis指定key查询不同排行榜中的前limit条数据
     * @param key 排行榜key
     * @param limit 查询数量
     * @return
     */
    private List<GoodsVo> getHotGoodsRankByKey(String key,Integer limit) {
        // 从redis里获销量取前 limit 个商品id
        Set<Object> salesRankSet = redisTemplate.
                opsForZSet().
                reverseRange(key, 0, limit);
        // 存放从redis里查出来的id
        List<Long> ids = new ArrayList();
        // 存放方法返回商品
        List<GoodsVo> goodsVoList = new ArrayList<>();

        // 如果key存在
        if (salesRankSet != null && !salesRankSet.isEmpty()) {
            // 遍历redis返回集合 并将其中内容加入到ids集合当中
            Iterator<Object> iterator = salesRankSet.iterator();
            while (iterator.hasNext()) {
                Integer next = (Integer)iterator.next();
                ids.add(Long.valueOf(next));
            }
            // 查询对应商品
            QueryWrapper<Goods> goodsQueryWrapper = new QueryWrapper<>();
            goodsQueryWrapper.in("id", ids);
            List<Goods> goodsList = goodsMapper.selectList(goodsQueryWrapper);
            for (Goods goods : goodsList) {
                goodsVoList.add(convertToVo(goods));
            }
        } else {
            throw new NoGoodsException();
        }
        return goodsVoList;
    }


    /**
     * 转成vo对象
     *
     * @param goods
     * @return
     */
    private GoodsVo convertToVo(Goods goods) {
        GoodsVo goodsVo = new GoodsVo();
        BeanUtils.copyProperties(goods, goodsVo);
        return goodsVo;
    }
}
